<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>智能推荐套餐 - 管理员</title>
    <!-- 引入 marked 和 github-markdown-css -->
    <script src="./js/marked.min.js"></script>
    <link rel="stylesheet" href="./css/github-markdown-light.css">
    <style>
        body {
            margin: 0;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
            background-color: #f0f2f5;
        }
        #container {
            max-width: 1200px;
            margin: 20px auto;
            padding: 20px;
            border-radius: 12px;
            background: #fafafa;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
        }
        .content-wrapper {
            display: flex;
            gap: 20px;
            margin-bottom: 20px;
        }
        .user-list-section {
            flex: 0 0 250px;
            border: 1px solid #d1d9e0;
            border-radius: 8px;
            background: #fff;
            overflow: hidden;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }
        .user-list-header {
            padding: 12px 16px;
            background: #f6f8fa;
            font-weight: 600;
            border-bottom: 1px solid #e1e4e8;
        }
        .user-list {
            max-height: 60vh;
            overflow-y: auto;
            padding: 10px;
        }
        .user-item {
            padding: 8px 12px;
            margin-bottom: 5px;
            border-radius: 6px;
            cursor: pointer;
            transition: background-color 0.2s, border-color 0.2s;
        }
        .user-item:hover {
            background-color: #f0f0f0;
        }
        .user-item.selected {
            background-color: #e3f2fd;
            border: 1px solid #90caf9;
        }
        .main-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            gap: 20px;
        }
        .user-detail-section {
            padding: 20px;
            background: #fff;
            border: 1px solid #d1d9e0;
            border-radius: 8px;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }
        .user-detail-header {
            font-weight: 600;
            margin-bottom: 16px;
            color: #1f2328;
            font-size: 16px;
        }
        .user-detail-content {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 16px;
        }
        .detail-item {
            display: flex;
            flex-direction: column;
        }
        .detail-label {
            font-size: 13px;
            color: #6b7280;
            margin-bottom: 4px;
        }
        .detail-value {
            font-size: 14px;
            color: #1f2328;
            font-weight: 500;
        }
        #msgDiv {
            flex: 1;
            max-height: 50vh;
            overflow-y: auto;
            padding: 20px;
            background: #ffffff;
            border-radius: 8px;
            border: 1px solid #d1d9e0;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
            display: flex;
            flex-direction: column;
            gap: 16px;
        }
        .markdown-body {
            box-sizing: border-box;
            min-width: 200px;
            max-width: 100%;
            margin: 0;
        }
        #ctrl {
            margin-top: 16px;
            display: flex;
            gap: 10px;
        }
        input[type="text"] {
            flex: 1;
            padding: 10px 12px;
            font-size: 14px;
            border: 1px solid #d9d9d9;
            border-radius: 6px;
            outline: none;
            transition: border-color 0.3s;
        }
        input[type="text"]:focus {
            border-color: #4096ff;
        }
        button {
            padding: 10px 20px;
            font-size: 14px;
            cursor: pointer;
            border: none;
            border-radius: 6px;
            transition: all 0.3s;
        }
        .btn-primary {
            background-color: #4096ff;
            color: white;
        }
        .btn-primary:hover:not(:disabled) {
            background-color: #3085ff;
        }
        .btn-secondary {
            background-color: #f0f0f0;
            color: #666;
        }
        .btn-secondary:hover:not(:disabled) {
            background-color: #e0e0e0;
        }
        button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
        .error {
            color: #ff4d4f;
            font-weight: bold;
        }
        .no-selection {
            color: #999;
            font-style: italic;
        }
        /* 聊天消息样式 */
        .message-wrapper {
            display: flex;
            gap: 8px;
            max-width: 75%;
        }
        .message-wrapper.user {
            align-self: flex-end;
        }
        .message-wrapper.system {
            align-self: flex-start;
        }
        .message-avatar {
            width: 32px;
            height: 32px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            font-weight: bold;
            color: white;
            flex-shrink: 0;
        }
        .message-avatar.user {
            background-color: #4096ff;
        }
        .message-avatar.system {
            background-color: #1890ff;
        }
        .message-content {
            padding: 12px 16px;
            border-radius: 12px;
            word-wrap: break-word;
        }
        .message-content.user {
            background-color: #4096ff;
            color: white;
        }
        .message-content.system {
            background-color: #f0f0f0;
            color: #333;
        }
        .message-content.markdown {
            white-space: pre-wrap;
        }
        .message-divider {
            text-align: center;
            color: #999;
            font-size: 12px;
            margin: 10px 0;
        }
        .message-divider span {
            background-color: #fff;
            padding: 0 10px;
        }
    </style>
</head>
<body>
<div id="container">
    <h2 style="font-size: 1.2em;">智能推荐套餐 - 管理员</h2>

    <div class="content-wrapper">
        <!-- 用户列表区域 -->
        <div class="user-list-section">
            <div class="user-list-header">用户列表</div>
            <div class="user-list" id="userList"></div>
        </div>

        <!-- 主内容区域 -->
        <div class="main-content">
            <!-- 用户详情区域 -->
            <div class="user-detail-section">
                <div class="user-detail-header">用户详情</div>
                <div class="user-detail-content" id="userDetail">
                    <div class="no-selection">请从左侧选择一个用户</div>
                </div>
            </div>

            <!-- 消息展示区域 -->
            <div id="msgDiv"><!-- 聊天消息会实时渲染到这里 --></div>
        </div>
    </div>

    <div id="ctrl">
        <input  id="question" type="text" placeholder="选择用户后，点击发送按钮发送消息" />
        <button id="sendBtn" class="btn-primary">发送</button>
        <button id="stopBtn" class="btn-secondary" disabled>停止</button>
    </div>
</div>

<script>
    // 环境切换开关：'dev' 开发环境（调用本地http接口），'prod' 生产环境（调用/api接口）
    const ENV_MODE = 'prod'; // 修改此值切换环境
    
    let es = null;          // 当前 EventSource 实例
    let selectedUser = null; // 当前选中的用户
    let currentResponseId = null; // 当前响应的消息ID
    const msgDiv = document.getElementById('msgDiv');
    const questionInput = document.getElementById('question');
    const sendBtn = document.getElementById('sendBtn');
    const stopBtn = document.getElementById('stopBtn');
    const userList = document.getElementById('userList');
    const userDetail = document.getElementById('userDetail');
    
    // 配置marked解析器
    marked.setOptions({
        breaks: true,
        gfm: true,
        headerIds: false,
        mangle: false
    });

    // 模拟用户数据
    const mockUsers = [
        {
            id: 1,
            userName: "张三",
            age: 28,
            occupation: "软件工程师",
            monthlyBudget: 1000,
            netDemand: "高",
            callDemand: "中",
            needIntlRoam: false,
            needVas: true,
            preferContract: true,
            extraRemark: "喜欢流量多的套餐"
        },
        {
            id: 2,
            userName: "李四",
            age: 35,
            occupation: "销售经理",
            monthlyBudget: 2000,
            netDemand: "中",
            callDemand: "高",
            needIntlRoam: true,
            needVas: true,
            preferContract: false,
            extraRemark: "经常出差国外"
        },
        {
            id: 3,
            userName: "王五",
            age: 22,
            occupation: "学生",
            monthlyBudget: 500,
            netDemand: "高",
            callDemand: "低",
            needIntlRoam: false,
            needVas: false,
            preferContract: false,
            extraRemark: "预算有限"
        },
        {
            id: 4,
            userName: "赵六",
            age: 45,
            occupation: "企业高管",
            monthlyBudget: 3000,
            netDemand: "高",
            callDemand: "高",
            needIntlRoam: true,
            needVas: true,
            preferContract: true,
            extraRemark: "需要高端商务套餐"
        },
        {
            id: 5,
            userName: "孙七",
            age: 30,
            occupation: "自由职业者",
            monthlyBudget: 800,
            netDemand: "中",
            callDemand: "中",
            needIntlRoam: false,
            needVas: false,
            preferContract: false,
            extraRemark: "对价格敏感"
        }
    ];

    // 从接口获取用户数据
    function fetchUsers() {
        // 根据环境选择接口地址
        const apiUrl = ENV_MODE === 'dev' 
            ? 'http://localhost:8181/ai/taocan/listUser' 
            : '/api/taocan/listUser';
            
        return fetch(apiUrl)
            .then(response => {
                if (!response.ok) {
                    throw new Error('接口调用失败');
                }
                return response.json();
            })
            .catch(error => {
                console.error('获取用户数据失败:', error);
                // 接口调用失败时，返回模拟数据作为备用
                return mockUsers;
            });
    }

    // 初始化用户列表
    function initUserList(users) {
        userList.innerHTML = '';
        users.forEach(user => {
            const userItem = document.createElement('div');
            userItem.className = 'user-item';
            userItem.textContent = user.userName;
            userItem.dataset.userId = user.id;
            userItem.addEventListener('click', () => selectUser(user));
            userList.appendChild(userItem);
        });
    }

    // 选择用户
    function selectUser(user) {
        // 移除其他用户的选中状态
        document.querySelectorAll('.user-item').forEach(item => {
            item.classList.remove('selected');
        });
        
        // 设置当前用户为选中状态
        selectedUser = user;
        if (selectedUser) {
            questionInput.value = `我是${selectedUser.userName}，给我推荐合适的套餐`;;
        } 
        const selectedItem = document.querySelector(`.user-item[data-user-id="${user.id}"]`);
        if (selectedItem) {
            selectedItem.classList.add('selected');
        }
        
        // 显示用户详情
        showUserDetail(user);
    }

    // 显示用户详情
    function showUserDetail(user) {
        userDetail.innerHTML = '';
        
        const detailFields = [
            { label: '用户名', value: user.userName },
            { label: '年龄', value: user.age },
            { label: '职业', value: user.occupation },
            { label: '月预算', value: `¥${user.monthlyBudget}` },
            { label: '网络需求', value: user.netDemand },
            { label: '通话需求', value: user.callDemand },
            { label: '国际漫游', value: user.needIntlRoam ? '是' : '否' },
            { label: '增值服务', value: user.needVas ? '是' : '否' },
            { label: '合约偏好', value: user.preferContract ? '是' : '否' },
            { label: '备注', value: user.extraRemark }
        ];
        
        detailFields.forEach(field => {
            const detailItem = document.createElement('div');
            detailItem.className = 'detail-item';
            
            const label = document.createElement('div');
            label.className = 'detail-label';
            label.textContent = field.label;
            
            const value = document.createElement('div');
            value.className = 'detail-value';
            value.textContent = field.value;
            
            detailItem.appendChild(label);
            detailItem.appendChild(value);
            userDetail.appendChild(detailItem);
        });
    }

    // 发送 + 接收
    function startSSE() {
        let content = questionInput.value.trim();
        
        // 如果选择了用户，则组装套餐推荐请求
        if (selectedUser) {
            if(!content){
                content = `我是${selectedUser.userName}，给我推荐合适的套餐`;
            }
            questionInput.value = content;
        } 

        if (!content) {
            alert('请选择一个用户或输入问题内容');
            return;
        }
        
        sendBtn.disabled = true;
        stopBtn.disabled = false;
        
        // 创建用户消息元素
        const userMessage = createUserMessage(content);
        msgDiv.appendChild(userMessage);
        
        // 清空输入框
        questionInput.value = '';
        
        // 创建系统消息容器（等待填充内容）
        currentResponseId = 'response-' + Date.now();
        const systemMessage = createSystemMessageContainer(currentResponseId);
        msgDiv.appendChild(systemMessage);
        
        // 滚动到底部
        scrollToBottom();

        // 1. 建立 SSE 连接，根据环境选择接口地址
        const sseUrl = ENV_MODE === 'dev' 
            ? `http://localhost:8181/ai/chat/sse/msg/1?content=${encodeURIComponent(content)}&role=user&model=deepseek` 
            : `/api/chat/sse/msg/1?content=${encodeURIComponent(content)}&role=user&model=deepseek`;
            
        es = new EventSource(sseUrl);

        // 2. 普通消息 → 实时渲染
        es.onmessage = e => {
            updateSystemMessage(currentResponseId, e.data);
        };

        // 3. 具名事件：后端主动通知结束
        es.addEventListener('end', e => {
            updateSystemMessage(currentResponseId, '\n\n---\n输出完毕');
            closeSSE();
        });

        // 4. 异常处理
        es.onerror = e => {
            console.error('SSE error', e);
            updateSystemMessage(currentResponseId, '\n\n<span class="error">连接异常，已停止接收</span>');
            closeSSE();
        };
    }

    // 创建用户消息元素
    function createUserMessage(content) {
        const wrapper = document.createElement('div');
        wrapper.className = 'message-wrapper user';
        
        const avatar = document.createElement('div');
        avatar.className = 'message-avatar user';
        avatar.textContent = '用';
        
        const messageContent = document.createElement('div');
        messageContent.className = 'message-content user';
        messageContent.textContent = content;
        
        wrapper.appendChild(avatar);
        wrapper.appendChild(messageContent);
        
        return wrapper;
    }

    // 创建系统消息容器
    function createSystemMessageContainer(id) {
        const wrapper = document.createElement('div');
        wrapper.className = 'message-wrapper system';
        wrapper.id = id;
        
        const avatar = document.createElement('div');
        avatar.className = 'message-avatar system';
        avatar.textContent = '智';
        
        const messageContent = document.createElement('div');
        messageContent.className = 'message-content system markdown-body';
        
        wrapper.appendChild(avatar);
        wrapper.appendChild(messageContent);
        
        return wrapper;
    }

    // 更新系统消息内容（带Markdown解析）
    function updateSystemMessage(id, content) {
        const messageWrapper = document.getElementById(id);
        if (!messageWrapper) return;
        
        const messageContent = messageWrapper.querySelector('.message-content');
        if (!messageContent) return;
        
        // 累积内容
        const currentContent = messageContent.getAttribute('data-original-content') || '';
        const newContent = currentContent + content;
        
        // 保存原始内容
        messageContent.setAttribute('data-original-content', newContent);
        
        // 解析Markdown并更新DOM
        try {
            messageContent.innerHTML = marked.parse(newContent);
        } catch (e) {
            console.error('Markdown解析错误:', e);
            messageContent.textContent = newContent;
        }
        
        // 滚动到底部
        scrollToBottom();
    }

    // 滚动到底部
    function scrollToBottom() {
        msgDiv.scrollTop = msgDiv.scrollHeight;
    }

    // 关闭连接
    function closeSSE() {
        if (es) {
            es.close();
            es = null;
        }
        sendBtn.disabled = false;
        stopBtn.disabled = true;
    }

    // 事件绑定
    sendBtn.addEventListener('click', startSSE);
    stopBtn.addEventListener('click', closeSSE);
    questionInput.addEventListener('keydown', e => {
        if (e.key === 'Enter') startSSE();
    });

    // 页面加载完成后初始化
    window.addEventListener('load', () => {
        fetchUsers().then(users => {
            initUserList(users);
        });
    });
</script>
</body>
</html>